home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 1999 August / SGI Freeware 1999 August.iso / dist / fw_xemacs.idb / usr / freeware / lib / xemacs-20.4 / lisp / modes / rexx-mode.el.z / rexx-mode.el
Encoding:
Text File  |  1998-05-21  |  22.8 KB  |  618 lines

  1. ;;; rexx-mode.el --- major mode for editing REXX program files
  2. ;; Keywords: languages
  3.  
  4. ;; Copyright (C) 1993 by Anders Lindgren.
  5.  
  6. ;; This file is part of XEmacs.
  7.  
  8. ;; XEmacs is free software; you can redistribute it and/or modify it
  9. ;; under the terms of the GNU General Public License as published by
  10. ;; the Free Software Foundation; either version 2, or (at your option)
  11. ;; any later version.
  12.  
  13. ;; XEmacs is distributed in the hope that it will be useful, but
  14. ;; WITHOUT ANY WARRANTY; without even the implied warranty of
  15. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16. ;; General Public License for more details.
  17.  
  18. ;; You should have received a copy of the GNU General Public License
  19. ;; along with XEmacs; see the file COPYING.  If not, write to the 
  20. ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  21. ;; Boston, MA 02111-1307, USA.
  22.  
  23. ;;; Synched up with: Not in FSF.
  24.  
  25. ;;; AUTHOR
  26. ;;;    Anders Lindgren, d91ali@csd.uu.se
  27. ;;;
  28. ;;;         Abbreviation table due to:
  29. ;;;    Johan Bergkvist, nv91-jbe@nada.kth.se
  30. ;;;
  31. ;;; USAGE
  32. ;;;    This file contains code for a GNU Emacs major mode for
  33. ;;;    editing REXX program files.
  34. ;;;
  35. ;;;     Type C-h m in Emacs for information on how to configurate
  36. ;;;    the rexx-mode, or see rexx-mode.doc.
  37. ;;;
  38. ;;;    Put the following lines into your .emacs and rexx-mode
  39. ;;;    will be automatically loaded when editing a REXX program.
  40. ;;;    If rexx-mode shall be used for files with other extensions
  41. ;;;    you can create more (cons ...) lines with these extensions.
  42. ;;;
  43. ;;;    (autoload 'rexx-mode "rexx-mode" "REXX mode" nil t)
  44. ;;;    (setq auto-mode-alist
  45. ;;;          (append
  46. ;;;           (list (cons "\\.rexx$"  'rexx-mode)
  47. ;;;             (cons "\\.elx$"   'rexx-mode)
  48. ;;;             (cons "\\.ncomm$" 'rexx-mode)
  49. ;;;             (cons "\\.cpr$"   'rexx-mode)
  50. ;;;                    )
  51. ;;;           auto-mode-alist))
  52. ;;;
  53. ;;; HISTORY
  54. ;;;    93-01-07 V0.1 ALi    Works for the first time.
  55. ;;;    92-01-11 V0.2 ALi    rexx-calc-indent totally rewritten.
  56. ;;;     93-03-08 V0.3 JB        rexx-indent-and-newline-and-indent added.
  57. ;;;                             Abbrev-table containing 173 entries created.
  58. ;;;                             rexx-check-expansion added.
  59. ;;;                             rexx-mode enables use of abbrev-table.
  60. ;;;    93-03-15 V0.4 ALi    abbrev-mode removed, better to call
  61. ;;;                 (abbrev-mode 1) from the hook.
  62. ;;;                case-fold-search set to t to recognize capital
  63. ;;;                 letters in keywords.
  64. ;;;                Old (setq case-fold-search nil) removed which
  65. ;;;                 prevented the recognition of END.
  66. ;;;                rexx-indent-and-newline-and-indent renamed to
  67. ;;;                 rexx-indent-newline-indent.
  68. ;;;                rexx-i-n-i now only expands abbrevs when
  69. ;;;                 buffer is in abbrev-mode.
  70. ;;;                New rexx-newline-and-indent added.
  71. ;;;    93-03-20      ALi     A serious bug in the routine for checking
  72. ;;;                strings and comments found and fixed.
  73. ;;;               V1.0 Relesed!    
  74. ;;;
  75.  
  76.  
  77. (provide 'rexx-mode)
  78.  
  79. (defgroup rexx nil
  80.   "Major mode for editing REXX program files"
  81.   :group 'languages)
  82.  
  83.  
  84. (defcustom rexx-indent 8
  85.   "*This variable contains the indentation in rexx-mode."
  86.   :type 'integer
  87.   :group 'rexx)
  88.  
  89. (defcustom rexx-end-indent 0
  90.   "*This variable indicates the relative position of the \"end\" in REXX mode."
  91.   :type 'integer
  92.   :group 'rexx)
  93.  
  94. (defcustom rexx-cont-indent 8
  95.   "*This variable indicates how far a continued line shall be intended."
  96.   :type 'integer
  97.   :group 'rexx)
  98.  
  99. (defcustom rexx-comment-col 32
  100.   "*This variable gives the desired comment column 
  101. for comments to the right of text."
  102.   :type 'integer
  103.   :group 'rexx)
  104.  
  105. (defcustom rexx-tab-always-indent t
  106.   "*Non-nil means TAB in REXX mode should always reindent the current line,
  107. regardless of where in the line point is when the TAB command is used."
  108.   :type 'boolean
  109.   :group 'rexx)
  110.  
  111. (defcustom rexx-special-regexp 
  112.   ".*\\(,\\|then\\|else\\)[ \t]*\\(/\\*.*\\*/\\)?[ \t]*$"
  113.   "*Regular expression for parsing lines which shall be followed by
  114. a extra indention"
  115.   :type 'regexp
  116.   :group 'rexx)
  117.  
  118. (defconst rexx-font-lock-keywords
  119.   (purecopy
  120.    (list
  121.     (cons (concat "\\<\\("
  122.      (mapconcat 'identity
  123.      '("address" "arg" "break" "call" "do" "drop" "echo" "else" "end"
  124.       "exit" "if" "interpret" "iterate" "leave" "nop" "numeric"
  125.       "options" "otherwise" "parse" "procedure" "pull" "push" "queue"
  126.       "return" "say" "select" "shell" "signal" "then" "trace" "upper"
  127.       "when" "value" "to" "by" "for" "forever" "while" "until" "form"
  128.       "digits" "fuzz" "scientific" "engineering" "failat" "prompt"
  129.       "results" "upper" "external" "source" "with" "command"
  130.       "function" "var" "version" "expose" "on" "off")
  131.      "\\|") "\\)\\>") 'font-lock-keyword-face)
  132.    '("\\(\\sw+\\):" 1 font-lock-function-name-face)))
  133.   "Additional expressions to highlight in Rexx mode.")
  134. (put 'rexx-mode 'font-lock-defaults '(rexx-font-lock-keywords))
  135.  
  136. (defvar rexx-mode-map nil
  137.   "Keymap for rexx-mode.")
  138. (if rexx-mode-map
  139.     nil
  140.   (setq rexx-mode-map (make-sparse-keymap))
  141.   (define-key rexx-mode-map "\t"   'rexx-indent-command)
  142.   (define-key rexx-mode-map "\C-m"  'rexx-indent-and-newline)
  143.   (define-key rexx-mode-map 'backspace 'backward-delete-char-untabify)
  144.   (define-key rexx-mode-map "\C-c\C-p" 'rexx-find-matching-do)
  145.   (define-key rexx-mode-map "\C-c\C-c" 'rexx-debug)
  146.   )
  147.  
  148. (defvar rexx-mode-syntax-table nil
  149.   "Syntax table in use in REXX-mode buffers.")
  150.  
  151. (if rexx-mode-syntax-table
  152.     ()
  153.   (setq rexx-mode-syntax-table (make-syntax-table))
  154.   (modify-syntax-entry ?\\ "\\" rexx-mode-syntax-table)
  155.   (modify-syntax-entry ?/ ". 14" rexx-mode-syntax-table)
  156.   (modify-syntax-entry ?* ". 23" rexx-mode-syntax-table)
  157.   (modify-syntax-entry ?+ "." rexx-mode-syntax-table)
  158.   (modify-syntax-entry ?- "." rexx-mode-syntax-table)
  159.   (modify-syntax-entry ?= "." rexx-mode-syntax-table)
  160.   (modify-syntax-entry ?% "." rexx-mode-syntax-table)
  161.   (modify-syntax-entry ?< "." rexx-mode-syntax-table)
  162.   (modify-syntax-entry ?> "." rexx-mode-syntax-table)
  163.   (modify-syntax-entry ?& "." rexx-mode-syntax-table)
  164.   (modify-syntax-entry ?| "." rexx-mode-syntax-table)
  165.   (modify-syntax-entry ?. "_" rexx-mode-syntax-table)
  166.   (modify-syntax-entry ?\' "\"" rexx-mode-syntax-table))
  167.  
  168. (defvar rexx-mode-abbrev-table nil
  169.   "*Abbrev table in use in rexx-mode buffers.")
  170.  
  171. (if rexx-mode-abbrev-table
  172.     nil
  173.   (define-abbrev-table 'rexx-mode-abbrev-table '(
  174.      ("address" "ADDRESS" rexx-check-expansion 0)
  175.      ("arg" "ARG" rexx-check-expansion 0)
  176.      ("break" "BREAK" rexx-check-expansion 0)
  177.      ("call" "CALL" rexx-check-expansion 0)
  178.      ("do" "DO" rexx-check-expansion 0)
  179.      ("drop" "DROP" rexx-check-expansion 0)
  180.      ("echo" "ECHO" rexx-check-expansion 0)
  181.      ("else" "ELSE" rexx-check-expansion 0)
  182.      ("end" "END" rexx-check-expansion 0)
  183.      ("exit" "EXIT" rexx-check-expansion 0)
  184.      ("if" "IF" rexx-check-expansion 0)
  185.      ("interpret" "INTERPRET" rexx-check-expansion 0)
  186.      ("iterate" "ITERATE" rexx-check-expansion 0)
  187.      ("leave" "LEAVE" rexx-check-expansion 0)
  188.      ("nop" "NOP" rexx-check-expansion 0)
  189.      ("numeric" "NUMERIC" rexx-check-expansion 0)
  190.      ("options" "OPTIONS" rexx-check-expansion 0)
  191.      ("otherwise" "OTHERWISE" rexx-check-expansion 0)
  192.      ("parse" "PARSE" rexx-check-expansion 0)
  193.      ("procedure" "PROCEDURE" rexx-check-expansion 0)
  194.      ("pull" "PULL" rexx-check-expansion 0)
  195.      ("push" "PUSH" rexx-check-expansion 0)
  196.      ("queue" "QUEUE" rexx-check-expansion 0)
  197.      ("return" "RETURN" rexx-check-expansion 0)
  198.      ("say" "SAY" rexx-check-expansion 0)
  199.      ("select" "SELECT" rexx-check-expansion 0)
  200.      ("shell" "SHELL" rexx-check-expansion 0)
  201.      ("signal" "SIGNAL" rexx-check-expansion 0)
  202.      ("then" "THEN" rexx-check-expansion 0)
  203.      ("trace" "TRACE" rexx-check-expansion 0)
  204.      ("upper" "UPPER" rexx-check-expansion 0)
  205.      ("when" "WHEN" rexx-check-expansion 0)
  206.      ("value" "VALUE" rexx-check-expansion 0)
  207.      ("to" "TO" rexx-check-expansion 0)
  208.      ("by" "BY" rexx-check-expansion 0)
  209.      ("for" "FOR" rexx-check-expansion 0)
  210.      ("forever" "FOREVER" rexx-check-expansion 0)
  211.      ("while" "WHILE" rexx-check-expansion 0)
  212.      ("until" "UNTIL" rexx-check-expansion 0)
  213.      ("form" "FORM" rexx-check-expansion 0)
  214.      ("digits" "DIGITS" rexx-check-expansion 0)
  215.      ("fuzz" "FUZZ" rexx-check-expansion 0)
  216.      ("scientific" "SCIENTIFIC" rexx-check-expansion 0)
  217.      ("engineering" "ENGINEERING" rexx-check-expansion 0)
  218.      ("failat" "FAILAT" rexx-check-expansion 0)
  219.      ("prompt" "PROMPT" rexx-check-expansion 0)
  220.      ("results" "RESULTS" rexx-check-expansion 0)
  221.      ("upper" "UPPER" rexx-check-expansion 0)
  222.      ("external" "EXTERNAL" rexx-check-expansion 0)
  223.      ("source" "SOURCE" rexx-check-expansion 0)
  224.      ("with" "WITH" rexx-check-expansion 0)
  225.      ("command" "COMMAND" rexx-check-expansion 0)
  226.      ("function" "FUNCTION" rexx-check-expansion 0)
  227.      ("var" "VAR" rexx-check-expansion 0)
  228.      ("version" "VERSION" rexx-check-expansion 0)
  229.      ("expose" "EXPOSE" rexx-check-expansion 0)
  230.      ("on" "ON" rexx-check-expansion 0)
  231.      ("off" "OFF" rexx-check-expansion 0)
  232.      ("abbrev" "ABBREV" rexx-check-expansion 0)
  233.      ("abs" "ABS" rexx-check-expansion 0)
  234.      ("addlib" "ADDLIB" rexx-check-expansion 0)
  235.      ("b2c" "B2C" rexx-check-expansion 0)
  236.      ("bitand" "BITAND" rexx-check-expansion 0)
  237.      ("bitchg" "BITCHG" rexx-check-expansion 0)
  238.      ("bitclr" "BITCLR" rexx-check-expansion 0)
  239.      ("bitcomp" "BITCOMP" rexx-check-expansion 0)
  240.      ("bitor" "BITOR" rexx-check-expansion 0)
  241.      ("bittst" "BITTST" rexx-check-expansion 0)
  242.      ("bitset" "BITSET" rexx-check-expansion 0)
  243.      ("c2b" "C2B" rexx-check-expansion 0)
  244.      ("c2d" "C2D" rexx-check-expansion 0)
  245.      ("c2x" "C2X" rexx-check-expansion 0)
  246.      ("center" "CENTER" rexx-check-expansion 0)
  247.      ("centre" "CENTRE" rexx-check-expansion 0)
  248.      ("close" "CLOSE" rexx-check-expansion 0)
  249.      ("compress" "COMPRESS" rexx-check-expansion 0)
  250.      ("compare" "COMPARE" rexx-check-expansion 0)
  251.      ("copies" "COPIES" rexx-check-expansion 0)
  252.      ("d2c" "D2C" rexx-check-expansion 0)
  253.      ("datatype" "DATATYPE" rexx-check-expansion 0)
  254.      ("delstr" "DELSTR" rexx-check-expansion 0)
  255.      ("delword" "DELWORD" rexx-check-expansion 0)
  256.      ("eof" "EOF" rexx-check-expansion 0)
  257.      ("errortext" "ERRORTEXT" rexx-check-expansion 0)
  258.      ("exists" "EXISTS" rexx-check-expansion 0)
  259.      ("export" "EXPORT" rexx-check-expansion 0)
  260.      ("freespace" "FREESPACE" rexx-check-expansion 0)
  261.      ("getclip" "GETCLIP" rexx-check-expansion 0)
  262.      ("getspace" "GETSPACE" rexx-check-expansion 0)
  263.      ("hash" "HASH" rexx-check-expansion 0)
  264.      ("import" "IMPORT" rexx-check-expansion 0)
  265.      ("index" "INDEX" rexx-check-expansion 0)
  266.      ("insert" "INSERT" rexx-check-expansion 0)
  267.      ("lastpos" "LASTPOS" rexx-check-expansion 0)
  268.      ("left" "LEFT" rexx-check-expansion 0)
  269.      ("length" "LENGTH" rexx-check-expansion 0)
  270.      ("max" "MAX" rexx-check-expansion 0)
  271.      ("min" "MIN" rexx-check-expansion 0)
  272.      ("open" "OPEN" rexx-check-expansion 0)
  273.      ("overlay" "OVERLAY" rexx-check-expansion 0)
  274.      ("pos" "POS" rexx-check-expansion 0)
  275.      ("pragma" "PRAGMA" rexx-check-expansion 0)
  276.      ("random" "RANDOM" rexx-check-expansion 0)
  277.      ("randu" "RANDU" rexx-check-expansion 0)
  278.      ("readch" "READCH" rexx-check-expansion 0)
  279.      ("readln" "READLN" rexx-check-expansion 0)
  280.      ("remlib" "REMLIB" rexx-check-expansion 0)
  281.      ("reverse" "REVERSE" rexx-check-expansion 0)
  282.      ("right" "RIGHT" rexx-check-expansion 0)
  283.      ("seek" "SEEK" rexx-check-expansion 0)
  284.      ("setclip" "SETCLIP" rexx-check-expansion 0)
  285.      ("show" "SHOW" rexx-check-expansion 0)
  286.      ("sign" "SIGN" rexx-check-expansion 0)
  287.      ("space" "SPACE" rexx-check-expansion 0)
  288.      ("storage" "STORAGE" rexx-check-expansion 0)
  289.      ("strip" "STRIP" rexx-check-expansion 0)
  290.      ("substr" "SUBSTR" rexx-check-expansion 0)
  291.      ("subword" "SUBWORD" rexx-check-expansion 0)
  292.      ("symbol" "SYMBOL" rexx-check-expansion 0)
  293.      ("time" "TIME" rexx-check-expansion 0)
  294.      ("trace" "TRACE" rexx-check-expansion 0)
  295.      ("translate" "TRANSLATE" rexx-check-expansion 0)
  296.      ("trim" "TRIM" rexx-check-expansion 0)
  297.      ("verify" "VERIFY" rexx-check-expansion 0)
  298.      ("word" "WORD" rexx-check-expansion 0)
  299.      ("wordindex" "WORDINDEX" rexx-check-expansion 0)
  300.      ("wordlength" "WORDLENGTH" rexx-check-expansion 0)
  301.      ("words" "WORDS" rexx-check-expansion 0)
  302.      ("writech" "WRITECH" rexx-check-expansion 0)
  303.      ("writeln" "WRITELN" rexx-check-expansion 0)
  304.      ("x2c" "X2C" rexx-check-expansion 0)
  305.      ("xrange" "XRANGE" rexx-check-expansion 0)
  306.      ("allocmem" "ALLOCMEM" rexx-check-expansion 0)
  307.      ("baddr" "BADDR" rexx-check-expansion 0)
  308.      ("bitxor" "BITXOR" rexx-check-expansion 0)
  309.      ("break_c" "BREAK_C" rexx-check-expansion 0)
  310.      ("break_d" "BREAK_D" rexx-check-expansion 0)
  311.      ("break_e" "BREAK_E" rexx-check-expansion 0)
  312.      ("break_f" "BREAK_F" rexx-check-expansion 0)
  313.      ("cache" "CACHE" rexx-check-expansion 0)
  314.      ("closeport" "CLOSEPORT" rexx-check-expansion 0)
  315.      ("d2x" "D2X" rexx-check-expansion 0)
  316.      ("date" "DATA" rexx-check-expansion 0)
  317.      ("delay" "DELAY" rexx-check-expansion 0)
  318.      ("delete" "DELETE" rexx-check-expansion 0)
  319.      ("error" "ERROR" rexx-check-expansion 0)
  320.      ("failure" "FAILURE" rexx-check-expansion 0)
  321.      ("find" "FIND" rexx-check-expansion 0)
  322.      ("forbid" "FORBID" rexx-check-expansion 0)
  323.      ("freemem" "FREEMEM" rexx-check-expansion 0)
  324.      ("getarg" "GETARG" rexx-check-expansion 0)
  325.      ("getpkt" "GETPKT" rexx-check-expansion 0)
  326.      ("halt" "HALT" rexx-check-expansion 0)
  327.      ("ioerr" "IOERR" rexx-check-expansion 0)
  328.      ("lines" "LINES" rexx-check-expansion 0)
  329.      ("makedir" "MAKEDIR" rexx-check-expansion 0)
  330.      ("next" "NEXT" rexx-check-expansion 0)
  331.      ("novalue" "NOVALUE" rexx-check-expansion 0)
  332.      ("null" "NULL" rexx-check-expansion 0)
  333.      ("offset" "OFFSET" rexx-check-expansion 0)
  334.      ("openport" "OPENPORT" rexx-check-expansion 0)
  335.      ("permit" "PERMIT" rexx-check-expansion 0)
  336.      ("rename" "RENAME" rexx-check-expansion 0)
  337.      ("reply" "REPLY" rexx-check-expansion 0)
  338.      ("showdir" "SHOWDIR" rexx-check-expansion 0)
  339.      ("showlist" "SHOWLIST" rexx-check-expansion 0)
  340.      ("sourceline" "SOURCELINE" rexx-check-expansion 0)
  341.      ("statef" "STATEF" rexx-check-expansion 0)
  342.      ("syntax" "SYNTAX" rexx-check-expansion 0)
  343.      ("trunc" "TRUNC" rexx-check-expansion 0)
  344.      ("typepkt" "TYPEPKT" rexx-check-expansion 0)
  345.      ("waitpkt" "WAITPKT" rexx-check-expansion 0)
  346.      ("x2d" "X2D" rexx-check-expansion 0))))
  347.  
  348. ;;;###autoload
  349. (defun rexx-mode ()
  350. "Major mode for editing REXX code.
  351. \\{rexx-mode-map}
  352.  
  353. Variables controlling indentation style:
  354.  rexx-indent
  355.     The basic indentation for do-blocks.
  356.  rexx-end-indent
  357.     The relative offset of the \"end\" statement. 0 places it in the
  358.     same column as the statements of the block. Setting it to the same
  359.     value as rexx-indent places the \"end\" under the do-line.
  360.  rexx-cont-indent
  361.     The indention for lines following \"then\", \"else\" and \",\"
  362.     (continued) lines.
  363.  rexx-tab-always-indent
  364.     Non-nil means TAB in REXX mode should always reindent the current 
  365.     line, regardless of where in the line the point is when the TAB
  366.     command is used.
  367.  
  368. If you have set rexx-end-indent to a nonzero value, you probably want to
  369. remap RETURN to rexx-indent-newline-indent. It makes sure that lines
  370. indents correctly when you press RETURN.
  371.  
  372. An extensive abbreviation table consisting of all the keywords of REXX are
  373. supplied. Expanded keywords are converted into upper case making it
  374. easier to distinguish them. To use this feature the buffer must be in
  375. abbrev-mode. (See example below.)
  376.  
  377. Turning on REXX mode calls the value of the variable rexx-mode-hook with
  378. no args, if that value is non-nil.
  379.  
  380. For example:
  381. (setq rexx-mode-hook '(lambda ()
  382.             (setq rexx-indent 4)
  383.             (setq rexx-end-indent 4)
  384.             (setq rexx-cont-indent 4)
  385.             (local-set-key \"\\C-m\" 'rexx-indent-newline-indent)
  386.             (abbrev-mode 1)
  387.             ))
  388.  
  389. will make the END aligned with the DO/SELECT. It will indent blocks and
  390. IF-statements four steps and make sure that the END jumps into the
  391. correct position when RETURN is pressed. Finally it will use the abbrev
  392. table to convert all REXX keywords into upper case."
  393.   (interactive)
  394.   (kill-all-local-variables)
  395.   (use-local-map rexx-mode-map)
  396.   (set-syntax-table rexx-mode-syntax-table)
  397.   (setq major-mode 'rexx-mode)
  398.   (setq mode-name "REXX")
  399.   (setq local-abbrev-table rexx-mode-abbrev-table)
  400.   (make-local-variable 'case-fold-search)
  401.   (setq case-fold-search t)
  402.   (make-local-variable 'paragraph-start)
  403.   (setq paragraph-start (concat "^$\\|" page-delimiter))
  404.   (make-local-variable 'paragraph-separate)
  405.   (setq paragraph-separate paragraph-start)
  406.   (make-local-variable 'paragraph-ignore-fill-prefix)
  407.   (setq paragraph-ignore-fill-prefix t)
  408.   (make-local-variable 'indent-line-function)
  409.   (setq indent-line-function 'rexx-indent-command)
  410.   (make-local-variable 'parse-sexp-ignore-comments)
  411.   (setq parse-sexp-ignore-comments t)
  412.   (make-local-variable 'comment-start)
  413.   (setq comment-start "/* ")
  414.   (make-local-variable 'comment-end)
  415.   (setq comment-end " */")
  416.   (make-local-variable 'comment-column)
  417.   (setq comment-column 32)
  418.   (make-local-variable 'comment-start-skip)
  419.   (setq comment-start-skip "/\\*+ *")
  420.   (make-local-variable 'comment-indent-hook)
  421.   (setq comment-indent-hook 'rexx-comment-indent)
  422.   (run-hooks 'rexx-mode-hook))
  423.  
  424.  
  425. (defun rexx-indent-command (&optional whole-exp)
  426.   "Indent the current line as REXX code."
  427.   (interactive "P")
  428.   (if whole-exp
  429.       (let ((shift-amt (rexx-indent-line))
  430.         beg
  431.         end)
  432.     (save-excursion
  433.       (if rexx-tab-always-indent
  434.           (beginning-of-line))
  435.       (setq beg (point))
  436.       (forward-sexp 1)
  437.       (setq end (point))
  438.       (goto-char beg)
  439.       (forward-line 1)
  440.       (setq beg (point)))
  441.     (if (> end beg)
  442.         (indent-code-rigidly beg end shift-amt)))
  443.     (if (and (not rexx-tab-always-indent)
  444.          (save-excursion
  445.           (skip-chars-backward " \t")
  446.           (not (bolp))))
  447.     (insert-tab)
  448.       (rexx-indent-line))))
  449.  
  450. (defun rexx-indent-line ()
  451.   "Indent the current line as REXX code.
  452. Return the amount the indentation changed by."
  453.   (let ((indent (rexx-calc-indent))
  454.     beg
  455.     shift-amt
  456.         (pos (- (point-max) (point))))
  457.     (beginning-of-line)
  458.     (setq beg (point))
  459.     (cond ((eq indent nil) (setq indent (current-indentation)))
  460.       ((eq indent t) (setq indent (rexx-calculate-indent-within-comment)))
  461.       ((looking-at "[ \t]*#") (setq indent 0))
  462.       (t (skip-chars-forward " \t")
  463.          (if (listp indent) (setq indent (car indent)))
  464.           ;; /* Sprekspecifik kod! */
  465.          (if (looking-at "end") (setq indent (- indent rexx-end-indent)))))
  466.     (skip-chars-forward " \t")
  467.     (setq shift-amt (- indent (current-column)))
  468.     (if (zerop shift-amt)
  469.     (if (> (- (point-max) pos) (point))
  470.         (goto-char (- (point-max) pos)))
  471.       (delete-region beg (point))
  472.       (indent-to indent)
  473.       (if (> (- (point-max) pos) (point))
  474.       (goto-char (- (point-max) pos))))
  475.     shift-amt))
  476.  
  477. (defun rexx-calc-indent ()
  478.   "Return the appropriate indentation for this line as an int."
  479.   (save-excursion
  480.     (beginning-of-line)
  481.     (let ((block (rexx-find-environment))
  482.       beg
  483.       state
  484.       indent)
  485.       (save-excursion (setq state (rexx-inside-comment-or-string)))
  486.       (cond ((or (nth 3 state) (nth 4 state))
  487.          (nth 4 state))    ;; Inside a comment or string
  488.         (t    
  489.          ;; Find line to indent current line after.
  490.          (rexx-backup-to-noncomment 1)
  491.          (beginning-of-line)
  492.          (setq beg (rexx-find-environment))
  493.          (while (> beg block)
  494.            (goto-char beg)
  495.            (beginning-of-line)
  496.            (setq beg (rexx-find-environment)))
  497.  
  498.          (if (> (point) block)         
  499.          ;; Check to see if we shall make a special indention
  500.          (if (looking-at rexx-special-regexp)
  501.              (+ (current-indentation) rexx-cont-indent)
  502.            ;; If not, find the basic indention by stepping
  503.            ;; by all special indented lines.
  504.            (progn
  505.              (setq indent (current-indentation))
  506.              (rexx-backup-to-noncomment 1)
  507.              (beginning-of-line)
  508.              (while (looking-at rexx-special-regexp)
  509.                (setq indent (current-indentation))
  510.                (rexx-backup-to-noncomment 1)
  511.                (beginning-of-line))
  512.              indent))
  513.            (if (= 1 block)
  514.            0
  515.          ;; Indent after the do-line.
  516.          (progn
  517.            (goto-char block)
  518.            (+ (current-indentation) rexx-indent)))))))))
  519.  
  520. (defun rexx-backup-to-noncomment (lim)
  521.   "Backup the point to the previous noncomment REXX line."
  522.   (let (stop)
  523.     (while (not stop)
  524.       (skip-chars-backward " \t\n\f" lim)
  525.       (if (and (>= (point) (+ 2 lim))
  526.            (save-excursion
  527.          (forward-char -2)
  528.          (looking-at "\\*/")))
  529.       (search-backward "/*" lim 'move)
  530.     (setq stop t)))
  531.     (>= (point) lim)))
  532.  
  533. (defun rexx-find-environment ()
  534.   "Return the position of the corresponding \"do\" or \"select\".
  535. If none found, return the beginning of buffer."
  536.   (save-excursion
  537.     (let ((do-level 1)
  538.       (cont t)
  539.       state)
  540.       (while (and cont (not (zerop do-level)))
  541.     (setq cont (re-search-backward "\\b\\(do\\|select\\|end\\)\\b" 1 t))
  542.     (save-excursion (setq state (rexx-inside-comment-or-string)))
  543.     (setq do-level (+ do-level
  544.               (cond ((or (nth 3 state) (nth 4 state)) 0)
  545.                 ((looking-at "do") -1)
  546.                 ((looking-at "select") -1)
  547.                 ((looking-at "end") +1)
  548.                 (t 0)))))
  549.  
  550.       (if cont (point) 1))))
  551.  
  552. (defun rexx-calculate-indent-within-comment ()
  553.   "Return the indentation amount for line, assuming that
  554. the current line is to be regarded as part of a block comment."
  555.   (let (end star-start)
  556.     (save-excursion
  557.       (beginning-of-line)
  558.       (skip-chars-forward " \t")
  559.       (setq star-start (= (following-char) ?\*))
  560.       (skip-chars-backward " \t\n")
  561.       (setq end (point))
  562.       (beginning-of-line)
  563.       (skip-chars-forward " \t")
  564.       (and (re-search-forward "/\\*[ \t]*" end t)
  565.        star-start
  566.        (goto-char (1+ (match-beginning 0))))
  567.       (current-column))))
  568.  
  569. (defun rexx-comment-indent ()
  570.   (if (looking-at "^/\\*")
  571.       0                ;Existing comment at bol stays there.
  572.     (save-excursion
  573.       (skip-chars-backward " \t")
  574.       (max (1+ (current-column))    ;Else indent at comment column
  575.        comment-column))))    ; except leave at least one space.
  576.  
  577. (defun rexx-find-matching-do ()
  578.   "Set mark, look for the \"do\" or \"select\" for the present block."
  579.   (interactive)
  580.   (set-mark-command nil)
  581.   (beginning-of-line)
  582.   (goto-char (rexx-find-environment)))
  583.  
  584. (defun rexx-check-expansion ()
  585.   "If abbrev was made within a comment or a string, de-abbrev!"
  586.   (let ((state (rexx-inside-comment-or-string)))
  587.     (if (or (nth 3 state) (nth 4 state))
  588.     (unexpand-abbrev))))
  589.  
  590. (defun rexx-inside-comment-or-string ()
  591.   "Check if the point is inside a comment or a string.
  592. It returns the state from parse-partial-sexp for the search that
  593. terminated on the points position"
  594.   (let ((origpoint (point))
  595.     state)
  596.     (save-excursion 
  597.       (goto-char 1)
  598.       (while (> origpoint (point))
  599.     (setq state (parse-partial-sexp (point) origpoint 0))))
  600.     state))
  601.  
  602. (defun rexx-indent-and-newline ()
  603.   "New newline-and-indent which expands abbrevs before running
  604. a regular newline-and-indent."
  605.   (interactive)
  606.   (if abbrev-mode 
  607.       (expand-abbrev))
  608.   (newline-and-indent))
  609.  
  610. (defun rexx-indent-newline-indent ()
  611.   "New newline-and-indent which expands abbrevs and indent the line
  612. before running a regular newline-and-indent."
  613.   (interactive)
  614.   (rexx-indent-command)
  615.   (if abbrev-mode 
  616.       (expand-abbrev))
  617.   (newline-and-indent))
  618.